
package com.hyst.seviceImpl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hyst.domain.*;
import com.hyst.repository.*;
import com.hyst.service.PurchaseCourseService;
import com.hyst.utils.DateUtil;
import com.hyst.utils.DateUtils;
import com.hyst.utils.UuidTool;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.LocalDateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @Description:
 * @Date：2018年09月11日 @author： dy
 * @version ：1.0 1.[2018年09月11日]
 */
@Service
public class PurchaseCourseServiceImpl implements PurchaseCourseService {

	@Autowired
	private PurchaseCourseMapper mapper;
	@Autowired
	private StudentMapper studentMapper;
	@Autowired
	private TeacherPeriodMapper teacherPeriodMapper;
	@Autowired
	private CurriculumScheduleMapper cmapper;
	@Autowired
	PurchaseCourseViewMapper pvmapper;
	@Autowired
	private PeriodMapper pmapper;
	@Autowired
	TeacherPeriodUsedMapper usedMapper;
	@Autowired
	private PeriodMapper periodMapper;
	@Autowired
	private RecommendMsgMapper recommendMsgMapper;


	@Override
	public Page<PurchaseCourse> list(final PurchaseCourse purchaseCourse) {
		final Page<PurchaseCourse> page = PageHelper.startPage(purchaseCourse.getPageNum(),
				purchaseCourse.getPageSize());
		mapper.select(purchaseCourse);
		return page;
	}

	@Override
	public Page<PurchaseCourseView> getByStudent(final PurchaseCourseView view) {
		final Page<PurchaseCourseView> page = PageHelper.startPage(view.getPageNum(), view.getPageSize());
		try {
			if(null !=view.getHoursEnrolled()){
				view.setHoursRemaining(view.getHoursEnrolled());
			}
			pvmapper.getView2(view);
			for(PurchaseCourseView purchaseCourseView:page.getResult()){
				Map<String,String> sqlMap = new HashMap<>();
				sqlMap.put("lessionId",purchaseCourseView.getMaterial());
				sqlMap.put("leveId",purchaseCourseView.getMaterialLevel());
				String lesson = pvmapper.getLesson(sqlMap);
				purchaseCourseView.setMaterialNameEn(lesson);
				if (null != purchaseCourseView.getState() && 0 == purchaseCourseView.getState()) {
					purchaseCourseView.setHoursRemaining(purchaseCourseView.getHoursEnrolled());
				}
			}
		}catch (Exception e){
			e.printStackTrace();
		}
		return page;
	}

	@Transactional
	@Override
	public PurchaseCourse insert(final PurchaseCourse purchaseCourse) {
		purchaseCourse.setUniqueid(UuidTool.randomUUID());
		mapper.insertSelective(purchaseCourse);
		Map<String,Object> sqlMap = new HashMap<>();
		sqlMap.put("oehour",purchaseCourse.getHoursEnrolled());
		sqlMap.put("orhour",purchaseCourse.getHoursEnrolled());
		sqlMap.put("uniqueid",purchaseCourse.getUniqueid());
		mapper.updateOrgHour(sqlMap);

		final String studentId = purchaseCourse.getStudentId();
		final StudentView stuInfo = studentMapper.getStuInfo(studentId);
		final String recommend = stuInfo.getRecommend();

		Map map = new HashMap();
		map.put("status","待发放");
		map.put("recommender",recommend);
		map.put("studentId",studentId);
		recommendMsgMapper.updateStatus(map);
		return purchaseCourse;
	}

	@Override
	public PurchaseCourse getByPriKey(final String uniqueid) {
		final PurchaseCourse purchaseCourse = mapper.selectByPrimaryKey(uniqueid);
		return purchaseCourse;
	}

	@Override
	public PurchaseCourse updateSelective(final PurchaseCourse purchaseCourse) {
		mapper.updateByPrimaryKeySelective(purchaseCourse);
		return purchaseCourse;
	}

	@Override
	public PurchaseCourse update(final PurchaseCourse purchaseCourse) {
		mapper.updateByPrimaryKey(purchaseCourse);
		return purchaseCourse;
	}

	@Override
	public PurchaseCourse delete(final String uniqueid) {
		PurchaseCourse purchaseCourse = new PurchaseCourse();
		purchaseCourse.setUniqueid(uniqueid);
		mapper.delete(purchaseCourse);
		cmapper.updateDelete(uniqueid);
		return null;
	}

	@Override
	public Page<Student> getStudents() {
		final Page<Student> page = PageHelper.startPage(1, 100000000);
		studentMapper.selectAll();
		return page;
	}

	@Override
	public PurchaseCourse getView(final String uniqueid) {
		return mapper.getOrder(uniqueid);
	}

	/**
	 * @Description:
	 * @param c
	 * @param length
	 * @return String
	 */
	private static String getEnd(final CurriculumSchedule c, final int length) {
		String end = "";
		final String start = c.getClassTime();
		final String[] strings = start.split(":");
		int m = Integer.valueOf(strings[1]) + length;
		final int h = m / 60 + Integer.valueOf(strings[0]);
		m = m % 60;
		final String ho = h > 9 ? h + "" : "0" + h;
		final String mi = m > 9 ? m + "" : "0" + m;
		end = ho + ":" + mi;
		System.out.println(m);
		return end;
	}

	@Transactional
	@Override
	public void updateClassTime(final PurchaseCourse purchaseCourseParam) throws Exception{
		PurchaseCourse purchaseCourse = mapper.selectByPrimaryKey(purchaseCourseParam.getUniqueid());
		purchaseCourse.setTimes(purchaseCourseParam.getTimes());

		String studentId = purchaseCourse.getStudentId();

		StudentView student = studentMapper.getStuInfo(studentId);
        String stuname = student.getEnName();
		if (purchaseCourse.getTimes().length > 0) {
			List<Integer> arr = new ArrayList<>();
			for (Integer num : purchaseCourse.getTimes()) {
				if (num != null) {
					arr.add(num);
				}
			}
			purchaseCourse.setTimes( arr.toArray(new Integer[arr.size()]));
		}
		purchaseCourse.setStudentId(null);
		purchaseCourse.setStuname("可用时段");
		purchaseCourse.setRemark("可用");
		purchaseCourse.setTemplPurId(null);
		teacherPeriodMapper.updateTeacherUsed(purchaseCourse);
		
		purchaseCourse.setStudentId(studentId);
		purchaseCourse.setStuname(stuname + "占用");
		purchaseCourse.setRemark("占用");
		teacherPeriodMapper.updateTeacherUsedIn(purchaseCourse);

		int maxCuId = teacherPeriodMapper.getMaxCuId(purchaseCourse.getUniqueid());
		Map<String, Object> sqlMap = new HashMap<>();
		sqlMap.put("id", purchaseCourse.getUniqueid());
		sqlMap.put("maxId", maxCuId);
		teacherPeriodMapper.updateCurDelete(sqlMap);

		//开始排课时间，有状态但不是默认状态第二日开始排课，否则从当前日期排课
		String startDate = DateUtils.formatDate(DateTime.now().toDate(), "yyyy-MM-dd");

        try {
            Map currmap = teacherPeriodMapper.getClassDate(maxCuId);
            if (currmap != null) {
//                if (currmap.get("state") != null && (Integer) currmap.get("state") != 0) {

                    Date date = DateUtils.parseDate(currmap.get("class_date").toString(), "yyyy-MM-dd");
                    startDate = DateUtil.addDayStr(date, 1);
//                } else {
//                    startDate = currmap.get("class_date").toString();
//				}
            }
        } catch (Exception e) {

        }

        purchaseCourse.setStartDate(startDate);
        List<TeacherPeriod> periodByPur = teacherPeriodMapper.getPeriodByPur(purchaseCourse.getUniqueid());
        List<String> week = teacherPeriodMapper.getStudentId(purchaseCourse.getUniqueid());
        List<CurriculumSchedule> curriculum = curriculum(purchaseCourse, purchaseCourse.getHoursRemaining(), periodByPur, week);
        for (CurriculumSchedule curriculumSchedule : curriculum) {
            List<CurriculumSchedule> list = new ArrayList<>();
            list.add(curriculumSchedule);
            cmapper.addAll(list);
        }
    }

	// 存在的问题 1、对象重复 2、时间为负数 3、时间段不对
	@Override
	public PurchaseCourse addTimes(final PurchaseCourse purchaseCourse) {
		try {
			mapper.updateByPrimaryKeySelective(purchaseCourse);
			purchaseCourse.setStuname(purchaseCourse.getStuname()+ "占用");
			purchaseCourse.setRemark("占用");
			if (purchaseCourse.getTimes() != null && purchaseCourse.getTimes().length > 0) {
				teacherPeriodMapper.setUsed(purchaseCourse);
				usedMapper.setUsed(purchaseCourse);
			} else {
				return purchaseCourse;
			}

			List<TeacherPeriod> periodByPur = teacherPeriodMapper.getPeriodByPur(purchaseCourse.getUniqueid());
			List<String> week = teacherPeriodMapper.getStudentId(purchaseCourse.getUniqueid());
			List<CurriculumSchedule> curriculum = curriculum(purchaseCourse, periodByPur, week);
			for(CurriculumSchedule curriculumSchedule :curriculum){
				List<CurriculumSchedule> list = new ArrayList<>();
				list.add(curriculumSchedule);
				cmapper.addAll(list);
			}
		} catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}

	public List<CurriculumSchedule> getInfo(final List<CurriculumSchedule> list) {
		final List<CurriculumSchedule> l = new ArrayList<>();
		for (int i = 0; i < list.size(); i++) {
			final CurriculumSchedule cs = list.get(i);
			if (i == 0) {
				l.add(cs);
			} else {
				final int j = l.size() - 1;
				final CurriculumSchedule ocs = l.get(j);
				if (ocs.getClassWeek() == cs.getClassWeek() && ocs.getClassTimeEnd().equals(cs.getClassTime())) {
					ocs.setClassTimeEnd(cs.getClassTimeEnd());
					ocs.setClassLength(ocs.getClassLength() + 15);
					l.set(j, ocs);
				} else {
					l.add(cs);
				}
			}
		}
		return l;
	}

	@Transactional
	@Override
	public int  reduction(String purchaseCourseId) {
		//释放时间
		int num=teacherPeriodMapper.reductionByPcUid(purchaseCourseId);
		//删除排课
		num+=cmapper.reductionByPcUid(purchaseCourseId);

		//课时还原
		cmapper.updateHour(purchaseCourseId);
		return num;
	}


	private List<CurriculumSchedule> curriculum(PurchaseCourse purchaseCourse,List<TeacherPeriod> teacherPeriods,List<String> weeks) throws Exception {
		//总课时
		int classTime = purchaseCourse.getHoursEnrolled();
		cmapper.updateHours(classTime);
		cmapper.updateHours2(classTime);

		List<Period> periods = periodMapper.selectAll();
		Map<Integer, Period> periodMap = new HashMap<>();
		for (Period p : periods) {
			periodMap.put(p.getId(), p);
		}

		Map<String, List<TeacherPeriod>> weekMap = new HashMap<>();
		for (TeacherPeriod period : teacherPeriods) {
			if (weekMap.containsKey(period.getWeek())) {
				List<TeacherPeriod> list = weekMap.get(period.getWeek());
				list.add(period);
				weekMap.put(period.getWeek(), list);
			} else {
				List<TeacherPeriod> list = new ArrayList<>();
				list.add(period);
				weekMap.put(period.getWeek(), list);
			}
		}

		//开始排课时间到6000天
		Date startDate = DateUtils.parseDate(purchaseCourse.getStartDate());
		List<Date> dates = DateUtils.getDatesBetweenTwoDate(startDate, DateUtils.addDays(startDate, 6000));
		List<Date> weekDate = DateUtils.getWeekDate(dates, weeks);

		List<CurriculumSchedule> curriculumSchedule = getCurriculumSchedule(purchaseCourse, weekDate, classTime, weekMap, periodMap);
		return curriculumSchedule;
	}

	private List<CurriculumSchedule> curriculum(PurchaseCourse purchaseCourse,int hours,List<TeacherPeriod> teacherPeriods,List<String> weeks) throws Exception {
		//总课时
		int classTime = hours;
		cmapper.updateHours(classTime);
		cmapper.updateHours2(classTime);

		List<Period> periods = periodMapper.selectAll();
		Map<Integer, Period> periodMap = new HashMap<>();
		for (Period p : periods) {
			periodMap.put(p.getId(), p);
		}

		Map<String, List<TeacherPeriod>> weekMap = new HashMap<>();
		for (TeacherPeriod period : teacherPeriods) {
			if (weekMap.containsKey(period.getWeek())) {
				List<TeacherPeriod> list = weekMap.get(period.getWeek());
				list.add(period);
				weekMap.put(period.getWeek(), list);
			} else {
				List<TeacherPeriod> list = new ArrayList<>();
				list.add(period);
				weekMap.put(period.getWeek(), list);
			}
		}

		//开始排课时间到6000天
		Date startDate = DateUtils.parseDate(purchaseCourse.getStartDate());
		List<Date> dates = DateUtils.getDatesBetweenTwoDate(startDate, DateUtils.addDays(startDate, 6000));
		List<Date> weekDate = DateUtils.getWeekDate(dates, weeks);

		List<CurriculumSchedule> curriculumSchedule = getCurriculumSchedule(purchaseCourse, weekDate, classTime, weekMap, periodMap);
		return curriculumSchedule;
	}


	private List<CurriculumSchedule> getCurriculumSchedule(PurchaseCourse purchaseCourse, List<Date> weekDate, int max,
														   Map<String, List<TeacherPeriod>> weekMap, Map<Integer, Period> periodMap) {
		int count = 0;
		List<CurriculumSchedule> inserts = new ArrayList<>();

		for (Date date : weekDate) {
			if (count > max) {
				return inserts;
			}

			int week = DateUtil.dayInWeek2(date);
			int hour = DateUtils.getHour(new Date());
			String ymd = DateUtils.formatDate(date, "yyyy-MM-dd");
			String nymd = DateUtils.formatDate(new Date(), "yyyy-MM-dd");

			List<TeacherPeriod> tps = weekMap.get(week + "");

			int minCount = 0;
			String begin = "";
			String end = "";

			if (count >= max) {
				return inserts;
			}


			if(tps !=null && tps.size()>0){
				for (TeacherPeriod t : tps) {
					if(t!=null){
						String name = periodMap.get(t.getTimeid()).getName();
						int hourD = Integer.valueOf(name.split("-")[0].split(":")[0]);

						//排课时间是今日 则课表开始时间需大于当前小时
						//排课时间大于今日
						if ((ymd.equals(nymd) && hourD > hour) || ymd.compareTo(nymd) > 0) {
							if (count >= max) {
								CurriculumSchedule cs = new CurriculumSchedule();
								cs.setPurchaseCourseId(purchaseCourse.getUniqueid());
								cs.setClassDate(date);
								cs.setClassWeek(week);
								cs.setClassTime(begin);
								cs.setClassTimeEnd(end);
								cs.setClassLength(minCount);
								cs.setMaterial(purchaseCourse.getMaterial());
								cs.setTeacherId(purchaseCourse.getTeacherId());
								cs.setStudentId(purchaseCourse.getStudentId());
								inserts.add(cs);
								return inserts;
							}
							if (StringUtils.isBlank(begin)) {
								begin = name.split("-")[0];
							}
							minCount += 15;
							count += 15;
							end = name.split("-")[1];
						}
					}
				}
			}

			if (StringUtils.isNotBlank(begin) && StringUtils.isNotBlank(end)) {
				CurriculumSchedule cs = new CurriculumSchedule();
				cs.setPurchaseCourseId(purchaseCourse.getUniqueid());
				cs.setClassDate(date);
				cs.setClassWeek(week);
				cs.setClassTime(begin);
				cs.setClassTimeEnd(end);
				cs.setClassLength(minCount);
				cs.setMaterial(purchaseCourse.getMaterial());
				cs.setTeacherId(purchaseCourse.getTeacherId());
				cs.setStudentId(purchaseCourse.getStudentId());
				inserts.add(cs);
			}
		}
		return inserts;
	}
}
